/*
 * HashBucketSerializer.cpp
 *
 *  Created on: Oct 26, 2012
 *      Author: m
 */

#include "HashBucketSerializer.h"

HashBucketSerializer::HashBucketSerializer() :
    m_registerSerializer( new HashRecordSerializer ),
    m_registerListSerializer( m_registerSerializer )
{
}

HashBucketSerializer::~HashBucketSerializer()
{
}

size_t HashBucketSerializer::serialize( const HashBucket& element,
        physical::byteStream block )
{
    physical::byte* blockPtr = (physical::byte*) block;
    size_t lastOperationBytesCount;
    size_t bytesCount;

    assert( m_registerListSerializer.computeSize( *element.m_records ) <= element.m_maxCapacity );

    // Se serializa el td y luego la lista

    // Serializo el id
    memcpy( blockPtr, &element.m_td, sizeof( HashBucket::TypeTD ) );
    bytesCount = sizeof( HashBucket::TypeTD );
    blockPtr += bytesCount;

    // Ahora serializo la lista de registros
    lastOperationBytesCount = m_registerListSerializer.serialize( *element.m_records, blockPtr );
    bytesCount += lastOperationBytesCount;
    blockPtr += bytesCount;

    return bytesCount;
}

size_t HashBucketSerializer::deserialize( const physical::byteStream block,
        HashBucket& element )
{
    // TODO: Indicar correctamente: "método no implementado"
    throw "method not implemented";
    return 0;
}

size_t HashBucketSerializer::computeSize( const HashBucket& element )
{
    size_t bytesCount;

    // Se serializa el td y luego la lista

    // Serializo el id
    bytesCount = sizeof( HashBucket::TypeTD );

    // Ahora serializo la lista de registros
    bytesCount += m_registerListSerializer.computeSize( element.m_records );

    return bytesCount;
}

size_t HashBucketSerializer::serialize( const _T_ptr& elementPtr,
        physical::byteStream block )
{
    return this->serialize( *elementPtr, block );
}

size_t HashBucketSerializer::deserialize( const physical::byteStream block,
        _T_ptr& elementPtr )
{
    physical::byte* blockPtr = (physical::byte*) block;
    size_t lastOperationBytesCount;
    size_t bytesCount;
    HashBucket::TypeTD td;
    HashBucket::HR_LIST_ptr records;

    // Se deserializa el td y luego la lista

    // deserializo el id
    memcpy( &td, blockPtr, sizeof( HashBucket::TypeTD ) );
    bytesCount = sizeof( HashBucket::TypeTD );
    blockPtr += bytesCount;

    // Ahora deserializo la lista de registros
    lastOperationBytesCount = m_registerListSerializer.deserialize( blockPtr, records );
    bytesCount += lastOperationBytesCount;
    blockPtr += bytesCount;

    // Finalmente creo el HashBucket ( de parámetros reducidos !!!! )
    elementPtr.reset( new HashBucket( td, records ) );

    return bytesCount;
}

size_t HashBucketSerializer::computeSize( const _T_ptr& elementPtr )
{
    return this->computeSize( *elementPtr );
}
